<?php

namespace App\Kuafu\Shop\Service;

use App\Kuafu\Base\Service\BaseService;
use App\Kuafu\Common\Service\CommonService;
use App\Kuafu\Config\Exceptions\ConfigException;
use App\Kuafu\Config\Model\ConfigModel;
use App\Kuafu\Config\Service\ConfigService;
use App\Kuafu\Export\Jobs\QueueExport;
use App\Kuafu\Export\Model\ExportDownloadModel;
use App\Kuafu\Order\Enum\OrderMerchantEnum;
use App\Kuafu\Shop\Enum\ShopCodeEnum;
use App\Kuafu\Shop\Exceptions\ShopException;
use App\Kuafu\Shop\Model\SourceMaterialTemplateModel;
use App\Kuafu\User\Exceptions\UserException;
use App\Kuafu\User\Service\AuthService;
use Endroid\QrCode\Builder\Builder;
use Endroid\QrCode\Encoding\Encoding;
use Endroid\QrCode\ErrorCorrectionLevel\ErrorCorrectionLevelHigh;
use Endroid\QrCode\RoundBlockSizeMode\RoundBlockSizeModeMargin;
use Endroid\QrCode\Writer\PngWriter;
use Exception;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Intervention\Image\Facades\Image;
use Kuafu\File\FileUtil;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

class ToolsService extends BaseService
{
    /**
     * 生成好评卡
     *
     * @param int $price
     * @param string $tel
     * @param string $wechatUrl
     * @param int $index
     * @return array
     * @throws ConfigException
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     * @throws UserException
     */
    public static function generatePraiseCard(int $price, string $tel, string $wechatUrl, int $index = 0): array
    {
        $card               = ConfigService::listByTypeAndKey('praiseCard', 'praiseCardConfig');
        $templateCard       = json_decode($card['praiseCardConfig'], true)[$index];
        $fileSystem         = getFileSystem();
        $praiseCardBasePath = app()->basePath() . "/public/storage/uploads/images/wmCard";
        //获取模板文件
        list($uprightTemplatePath, $reverseTemplatePath, $initFileGroup) = self::getPraiseCardTemplate(
            $index,
            $templateCard,
            $fileSystem,
            $praiseCardBasePath
        );

        $uid            = AuthService::getUserId();
        $userFilePrefix = md5($uid);
        $wmCardUserPath = vsprintf("%s/%s/%s/%s/", [
            $praiseCardBasePath,
            "user",
            substr($userFilePrefix, 0, 2),
            substr($userFilePrefix, 2, 2)
        ]);

        if (!$fileSystem->isDirectory($wmCardUserPath)) {
            $fileSystem->makeDirectory($wmCardUserPath, 0777, true);
        }
        $finalWechatPic = $wmCardUserPath . "{$userFilePrefix}_{$uid}_wechat.png";
        foreach ($templateCard["position"] as $picName => $item) {
            switch ($picName) {
                case "qrCode":
                    $query = Builder::create()
                                    ->writer(new PngWriter())
                                    ->writerOptions([])
                                    ->data($wechatUrl)
                                    ->encoding(new Encoding('UTF-8'))
                                    ->errorCorrectionLevel(new ErrorCorrectionLevelHigh())
                                    ->size($item['size'])
                                    ->margin($item['margin'])
                                    ->roundBlockSizeMode(new RoundBlockSizeModeMargin());
                    if (isset($initFileGroup["kFlogo"])) {
                        $query->logoPath($initFileGroup["kFlogo"]);
                    }
                    $result = $query->build();
                    $result->saveToFile($finalWechatPic);
                    break;
                case "upright":
                case "reverse":
                    // 正面卡片上的文字信息
                    // 用户卡片正面图
                    $userImg = $wmCardUserPath . "{$userFilePrefix}_{$uid}_{$picName}.png";
                    $query   = Image::make($picName == "upright" ? $uprightTemplatePath : $reverseTemplatePath);
                    foreach ($item as $imgAttrName => $imgAttrConfig) {
                        $text = "";
                        switch ($imgAttrName) {
                            case "price":
                                $text = $price;
                                break;
                            case "tel":
                                $text = $tel;
                                break;
                            case "qrCode":
                                $query->insert($finalWechatPic, $imgAttrConfig['align'],
                                    $imgAttrConfig['x'], $imgAttrConfig['y']);
                                break;
                        }
                        if ($text) {
                            $query->text($text, $imgAttrConfig['x'], $imgAttrConfig['y'],
                                function ($font) use ($imgAttrConfig, $imgAttrName, $initFileGroup) {
                                    if (isset($imgAttrConfig["color"])) {
                                        $font->color($imgAttrConfig["color"]);
                                    }
                                    if (isset($imgAttrConfig["fontSize"])) {
                                        $font->size($imgAttrConfig["fontSize"]);
                                    }
                                    if (isset($initFileGroup[$imgAttrName . "Front"])) {
                                        $font->file($initFileGroup[$imgAttrName . "Front"]);
                                    }
                                });
                        }
                    }
                    $query->resolution(600, 600)->save($userImg);
                    break;
            }
        }

        // 对外输出的文件信息
        $outFileName = str_replace($praiseCardBasePath, "wmCard", $wmCardUserPath . "{$userFilePrefix}_{$uid}");
        // 输出前段地址
        return [
            'lists' => [
                'upright' => CommonService::joinImageUrl($outFileName . '_upright.png') . '?t=' . time(),
                'reverse' => CommonService::joinImageUrl($outFileName . '_reverse.png') . '?t=' . time(),
            ]
        ];
    }

    public static function genWaiMaiPic(
        $price,
        $tel,
        $wechatUrl,
        int $index = 0
    ) {
        // 外卖好评卡的 文件目录
        $destinationPath = public_path() . '/storage/uploads/images/wmCard/resource';
        // 外卖好评卡的 用户生成图片目录
        $wmCardUserPath = public_path() . '/storage/uploads/images/wmCard/user/';
        // 用户信息文件名称
        $userFile = $wmCardUserPath . AuthService::getUserId() . md5(AuthService::getUserId());

        // 用户卡片正面图
        $userUpright = $userFile . '_upright.png';
        // 用户背面图
        $userReverse = $userFile . '_reverse.png';
        // 数据值 [ json 数据]
        $picDataAll = [
            'selectEd'  => 0,
            'cardValue' => [
                [
                    'originFile' => [
                        'logo'    => '/kf-logo.png',
                        'upright' => '/upright0.png',
                        'reverse' => '/reverse0.png'
                    ],
                    'qrCode'     => [
                        'size'   => 442,
                        'margin' => 10,
                    ],
                    'upright'    => [
                        'price' => [
                            'x'        => 634,
                            'y'        => 2286,
                            'fontSize' => 180,
                            'font'     => '/price-font.ttf',
                            'color'    => '#A91F24'
                        ]
                    ],
                    'reverse'    => [
                        'qrCode' => [
                            'align' => 'center',
                            'x'     => -40,
                            'y'     => 130
                        ],
                        'price'  => [
                            'x'        => 824,
                            'y'        => 648,
                            'fontSize' => 206,
                            'font'     => '/price-font.ttf',
                            'color'    => '#E71E2C'
                        ],
                        'tel'    => [
                            'x'        => 528,
                            'y'        => 2308,
                            'fontSize' => 54,
                            'font'     => '/tel-font.ttf',
                            'color'    => '#000000'
                        ]
                    ]
                ]
            ]
        ];

        $card       = ConfigService::listByTypeAndKey('waiMaiCard', 'waiMaiCardConfig');
        $picDataAll = json_decode($card['waiMaiCardConfig'], true);


        $picDataValue = $picDataAll['cardValue'][$picDataAll['selectEd']];

        $upright                                  = $destinationPath . $picDataValue['originFile']['upright'];
        $reverse                                  = $destinationPath . $picDataValue['originFile']['reverse'];
        $erCodeLogoUrl                            = $destinationPath . $picDataValue['originFile']['logo'];
        $picDataValue['upright']['price']['font'] = $destinationPath . $picDataValue['upright']['price']['font'];
        $picDataValue['reverse']['price']['font'] = $destinationPath . $picDataValue['reverse']['price']['font'];
        $picDataValue['reverse']['tel']['font']   = $destinationPath . $picDataValue['reverse']['tel']['font'];
        $finalWechatPic                           = $userFile . '_wechat.png';

        $result = Builder::create()
                         ->writer(new PngWriter())
                         ->writerOptions([])
                         ->data($wechatUrl)
                         ->encoding(new Encoding('UTF-8'))
                         ->errorCorrectionLevel(new ErrorCorrectionLevelHigh())
                         ->size($picDataValue['qrCode']['size'])
                         ->margin($picDataValue['qrCode']['margin'])
                         ->roundBlockSizeMode(new RoundBlockSizeModeMargin())
                         ->logoPath($erCodeLogoUrl)
                         ->build();

        $result->saveToFile($finalWechatPic);

        // 正面卡片上的文字信息
        Image::make($upright)
             ->text($price, $picDataValue['upright']['price']['x'], $picDataValue['upright']['price']['y'],
                 function ($font) use ($picDataValue) {
                     $font->file($picDataValue['upright']['price']['font']);
                     $font->size($picDataValue['upright']['price']['fontSize']);
                     $font->color($picDataValue['upright']['price']['color']);
                 })
             ->resolution(600, 600)
             ->save($userUpright);

        // 背面卡片上的文字信息
        Image::make($reverse)
             ->insert($finalWechatPic, $picDataValue['reverse']['qrCode']['align'],
                 $picDataValue['reverse']['qrCode']['x'], $picDataValue['reverse']['qrCode']['y'])
             ->text($price, $picDataValue['reverse']['price']['x'], $picDataValue['reverse']['price']['y'],
                 function ($font) use ($picDataValue) {
                     $font->file($picDataValue['reverse']['price']['font']);
                     $font->size($picDataValue['reverse']['price']['fontSize']);
                     $font->color($picDataValue['reverse']['price']['color']);
                 })
             ->text($tel, $picDataValue['reverse']['tel']['x'], $picDataValue['reverse']['tel']['y'],
                 function ($font) use ($picDataValue) {
                     $font->file($picDataValue['reverse']['tel']['font']);
                     $font->size($picDataValue['reverse']['tel']['fontSize']);
                     $font->color($picDataValue['reverse']['tel']['color']);
                 })
             ->resolution(600, 600)
             ->save($userReverse);

        // 对外输出的文件信息
        $outFileName = '/wmCard/user/' . AuthService::getUserId() . md5(AuthService::getUserId());
        // 输出前段地址
        return [
            'lists' => [
                'upright' => CommonService::joinImageUrl($outFileName . '_upright.png') . '?t=' . time(),
                'reverse' => CommonService::joinImageUrl($outFileName . '_reverse.png') . '?t=' . time(),
            ]
        ];
    }


    /**
     * @param int $index
     * @param array $templateCard
     * @param Filesystem $fileSystem
     * @param string $praiseCardBasePath
     * @return array
     */
    public static function getPraiseCardTemplate(
        int $index,
        array $templateCard,
        Filesystem $fileSystem,
        string $praiseCardBasePath
    ): array {
        $templateBasePath = $praiseCardBasePath . "/template/{$index}/";

        if (!$fileSystem->isDirectory($templateBasePath)) {
            $fileSystem->makeDirectory($templateBasePath, 0777, true);
        }

        $generateUniqueKey = md5(collect($templateCard)->only(["initFile", "template"])->toJson());
        $generateAgain     = false;
        if ($fileSystem->exists($templateBasePath . "generateUniqueKey.txt")) {
            $lastUniqueKey = file_get_contents($templateBasePath . "generateUniqueKey.txt");
            if (empty($lastUniqueKey) || $lastUniqueKey != $generateUniqueKey) {
                $generateAgain = true;
                $fileSystem->put($templateBasePath . "generateUniqueKey.txt", $generateUniqueKey);
            }
        } else {
            $generateAgain = true;
            $fileSystem->put($templateBasePath . "generateUniqueKey.txt", $generateUniqueKey);
        }

        $initFileGroup = [];

        collect($templateCard["initFile"])->each(function ($val, $key) use (
            $fileSystem,
            $templateBasePath,
            &$initFileGroup,
            $generateAgain
        ) {
            $filePath = vsprintf(
                "%s/%s.%s",
                [$templateBasePath, $key, pathinfo($val)['extension']]
            );

            if (!$fileSystem->exists($filePath) || $generateAgain) {
                $fileSystem->put($filePath, file_get_contents($val));
            }

            $initFileGroup[$key] = $filePath;
        });

        $uprightTemplatePath = vsprintf(
            "%s%s.%s",
            [$templateBasePath, "upright", pathinfo($templateCard["template"]["upright"])['extension']]
        );

        if (!$fileSystem->exists($uprightTemplatePath) || $generateAgain) {
            $fileSystem->put($uprightTemplatePath, file_get_contents($templateCard["template"]["upright"]));
        }
        $reverseTemplatePath = "";
        if ($templateCard["template"]["reverse"]) {
            $reverseTemplatePath = vsprintf(
                "%s%s.%s",
                [$templateBasePath, "reverse", pathinfo($templateCard["template"]["reverse"])['extension']]
            );
            if (!$fileSystem->exists($reverseTemplatePath) || $generateAgain) {
                $fileSystem->put($reverseTemplatePath, file_get_contents($templateCard["template"]["reverse"]));
            }
        }

        return [$uprightTemplatePath, $reverseTemplatePath, $initFileGroup];
    }


    /**
     * 物料素材模版列表
     * @param $type
     * @return array
     */
    public static function list($type): array
    {
        $list = [];
        SourceMaterialTemplateModel::query()
            ->when($type > 0, function ($query) use ($type) {
                $query->where("type", $type);
            })
            ->orderBy("sort")->each(
                function ($v) use (&$list, &$imgQuality) {
                    $list[] = [
                        'id'               => $v->id,
                        'name'             => $v->name,                                                                                  //模版名称
                        'url'              => self::urlHandle($v->url, $v->type),                                                        //预览图
                        'reverseUrl'       => self::urlHandle($v->reverseUrl, $v->type),                                                 //背面预览图
                        'thumbnail'        => self::urlHandle($v->thumbnail, $v->type),                                                  //缩略图
                        'reverseThumbnail' => self::urlHandle($v->reverseThumbnail, $v->type),                                           //背面缩略图
                        'type'             => $v->type,                                                                                  //素材类型 1：开业活动免费吃 2 ：开业活动进店送 3 ：招聘海报 4 ：好评卡外卖海报
                        'size'             => $v->size,                                                                                  //模版图片尺寸（cm）
                        'sort'             => $v->sort,                                                                                  //排序 越小越靠前
                        'typeText'         => SourceMaterialTemplateModel::TEMPLATE_TYPE_TEXT[$v->type] ?? "",
                    ];
                }
            );
        return $list;
    }

    /**
     * URL处理
     * @param string $url
     * @param int $type
     * @return string
     */
    public static function urlHandle(string $url, int $type = SourceMaterialTemplateModel::TEMPLATE_TYPE_OPEN_SHOP): string
    {
        if (!$url) {
            return $url;
        }
        $imgQuality = '?x-oss-process=image/format,jpg/quality,q_40';//对原图按百分比进行质量压缩
        if (in_array($type, [SourceMaterialTemplateModel::TEMPLATE_TYPE_PRAISE_CARD, SourceMaterialTemplateModel::TEMPLATE_TYPE_OPEN_SHOP])) {//好评卡外卖海报 图片比较小不用再压缩了-压缩会糊
            $imgQuality = '';
        }
        return FileUtil::domain() . '/' . $url . $imgQuality;
    }

    /**
     * 根据选择物料素材模版id创建
     * @param int $shopId
     * @param int $id
     * @param int $userId
     * @param int $price
     * @param int $num
     * @param string $tel
     * @param string $wechatUrl
     * @param string $address
     * @param string $recruitmentTitle
     * @param string $recruitmentRequire
     * @param string $recruitmentExtra
     * @param string $recruitmentTitleRight
     * @param string $recruitmentRequireRight
     * @param array $data
     * @return array
     * @throws ShopException
     */
    public static function create(
        int $shopId,
        int $id,
        int $userId,
        int $price,
        int $num,
        string $tel,
        string $wechatUrl,
        string $address,
        string $recruitmentTitle,
        string $recruitmentRequire,
        string $recruitmentExtra,
        string $recruitmentTitleRight,
        string $recruitmentRequireRight,
        array  $data
    ): array
    {
        try {
            $info = SourceMaterialTemplateModel::getInfoById($id);//模版信息
            if (!$info) {
                throw new ShopException(ShopCodeEnum::ERR_NOT_FOUND_MATERIAL_TEMPLATE);
            }
            $shopInfo = ShopService::getShopInfo($shopId);//店铺信息
            if (!$shopInfo) {
                throw new ShopException(ShopCodeEnum::ERR_SHOP_ID_NO_EXIST);
            }
//            $tel      = $shopInfo['shopMobile'];
            if ($price && strlen($price) > 1) {//金额
                $price = substr($price, 0, 1);
            }
            if ($num && strlen($num) > 4) {//数量
                $num = substr($num, 0, 4);
            }
            if ($shopInfo['name'] && mb_strlen($shopInfo['name']) > 34) {//店铺名称
                $shopInfo['name'] = mb_substr($shopInfo['name'], 0, 34);
            }
            if ($shopInfo['shopContact'] && mb_strlen($shopInfo['shopContact']) > 3) {//店铺联系人
                $shopInfo['shopContact'] = mb_substr($shopInfo['shopContact'], 0, 3);
            }
            /*if ($address && mb_strlen($address) > 60) {//招聘地址
                $address = mb_substr($address, 0, 60);
            }
            if ($recruitmentExtra && mb_strlen($recruitmentExtra) > 19) {//招聘额外信息
                $recruitmentExtra = mb_substr($recruitmentExtra, 0, 19);
            }
            if ($recruitmentRequireRight) {//两个招聘内容
                if (mb_strlen($recruitmentRequireRight) > 96) {
                    $recruitmentRequireRight = mb_substr($recruitmentRequireRight, 0, 96);
                }
                if ($recruitmentRequire && mb_strlen($recruitmentRequire) > 104) {
                    $recruitmentRequire = mb_substr($recruitmentRequire, 0, 104);
                }
            } else {//单个招聘内容
                if ($recruitmentRequire && mb_strlen($recruitmentRequire) > 200) {
                    $recruitmentRequire = mb_substr($recruitmentRequire, 0, 200);
                }
            }
            if ($recruitmentTitle && mb_strlen($recruitmentTitle) > 4) {//招聘标题
                $recruitmentTitle = mb_substr($recruitmentTitle, 0, 4);
            }
            if ($recruitmentTitleRight && mb_strlen($recruitmentTitleRight) > 4) {
                $recruitmentTitleRight = mb_substr($recruitmentTitleRight, 0, 4);
            }*/
            $shopArchivesInfo       = ShopArchivesService::getArchivesInfo($shopId);//门店附加信息
            if (!$shopArchivesInfo) {
                throw new ShopException(ShopCodeEnum::ERR_NOT_FOUND_SHOP_ARCHIVES);
            }
            $isReverse = false;// 是否有背面图
            //1、开业活动-免费吃  （企业微信群二维码）
            //2、开业活动-进店送 （企业微信群二维码）
            //3、好评卡 （个人微信二维码）
            //4、门店海报（个人微信二维码）
            $createTemplateData = [];
            switch ($info['type']) {
                case SourceMaterialTemplateModel::TEMPLATE_TYPE_PRAISE_CARD://好评卡
                    if (!$price || !$tel) {
                        throw new ShopException(ShopCodeEnum::ERR_INPUT_MATERIAL_TEMPLATE);
                    }
                    if (!$shopArchivesInfo['wechatUrl']) {
                        throw new ShopException(ShopCodeEnum::ERR_NOT_FOUND_SHOP_ARCHIVES);
                    }
                    $isReverse = true;
                    $createTemplateData = [
                        'price'     => $price,                        //金额
                        'tel'       => $tel,                          //联系电话
                        'wechatUrl' => $shopArchivesInfo['wechatUrl'],//微信二维码
                    ];
                    break;
                case SourceMaterialTemplateModel::TEMPLATE_TYPE_OPENING_ACTIVITIES_FREE://开业活动免费吃
                case SourceMaterialTemplateModel::TEMPLATE_TYPE_OPENING_ACTIVITIES_IN_SHOP://开业活动进店送
                    if (!$num) {
                        throw new ShopException(ShopCodeEnum::ERR_INPUT_MATERIAL_TEMPLATE);
                    }
                    if (!$shopArchivesInfo['eWechatUrl']) {
                        throw new ShopException(ShopCodeEnum::ERR_NOT_FOUND_SHOP_ARCHIVES);
                    }
                    $createTemplateData = [
                        'num'       => $num,                                                 //数量
                        'smallNum'  => $num,                                                 //小字-数量
                        'wechatUrl' => $shopArchivesInfo['eWechatUrl'],                      //微信二维码
                        'shopName'  => $shopInfo['name'],                                    //店铺名称
                    ];
                    break;
                case SourceMaterialTemplateModel::TEMPLATE_TYPE_RECRUITMENT_POSTER://招聘海报
                    if (!$recruitmentTitle || !$recruitmentRequire) {
                        throw new ShopException(ShopCodeEnum::ERR_INPUT_MATERIAL_TEMPLATE);
                    }
                    /*if (!$shopArchivesInfo['wechatUrl']) {
                        throw new ShopException(ShopCodeEnum::ERR_NOT_FOUND_SHOP_ARCHIVES);
                    }*/
                    $createTemplateData = [
                        'recruitmentTitle'        => $recruitmentTitle,                                                //招聘标题
                        'recruitmentRequire'      => $recruitmentRequire,                                              //招聘要求
                        'recruitmentTitleRight'   => $recruitmentTitleRight,                                           //右边招聘标题
                        'recruitmentRequireRight' => $recruitmentRequireRight,                                         //右边招聘要求
                        'recruitmentShopAddress'  => $address,                                                         //$shopInfo['address'],              //招聘门店地址
                        'wechatUrl'               => $shopArchivesInfo['wechatUrl'] ?? "",                                   //微信二维码
                        'person'                  => $shopInfo['shopContact'],                                         //联系人
                        'tel'                     => $tel,                                                             //联系电话
                        'recruitmentExtra'        => $recruitmentExtra,                                                //招聘额外信息
                    ];
                    break;
            }
            if (!$createTemplateData && $data) {
                $createTemplateData = $data;
            }
            if ($info['type'] == SourceMaterialTemplateModel::TEMPLATE_TYPE_PRIVATE_ACTIVITY) {

                // 单个模版需要匹配信息
                $tempData = ConfigService::getConfigDetail('tools', 'activityMaterialsOneConfig')['value'] ?? [];
                $tempData = collect($tempData)->keyBy('id')->toArray();
                if ($tempData && isset($tempData[$info['id']]) && $tempData[$info['id']]) {
                    foreach ($tempData[$info['id']] as $k => $temp) {
                        if (in_array($k, ['input2', 'input3'])) {
                            $createTemplateData[$k] = $temp;
                        }
                        $isReverse = true;
                    }
                }
            }
            if (!$createTemplateData) {
                throw new ShopException(ShopCodeEnum::ERR_INPUT_MATERIAL_TEMPLATE);
            }
            //合成图片 队列生成 上传到oss
//            self::generateTemplateImg($info, $createTemplateData, $userId, $shopId);dd(11);
            $showStartAt = $showEndAt = time();
            $params = [
                'shopId'             => $shopId,
                'shopIds'            => [],
                'showTimeTab'        => OrderMerchantEnum::SHOW_TIME_TAB_TODAY,
                'showStartAt'        => $showStartAt,
                'showEndAt'          => $showEndAt,
                'templateInfo'       => [
                    'id'    => $info['id'],
                    'name'  => $info['name'],
                    'value' => $info['value'],
                    'type'  => $info['type'],
                    'size'  => $info['size'],
                ],
                'createTemplateData' => $createTemplateData,
                'userId'             => $userId,
                'imgType'            => SourceMaterialTemplateModel::TEMPLATE_IMG_TYPE_UPRIGHT,
            ];

            $export = (new ExportDownloadModel)->add(ExportDownloadModel::CLIENT_TYPE_APP, ExportDownloadModel::FILE_TYPE_APP_SOURCE_MATERIAL_TEMPLATE, $params);

            dispatch(new QueueExport($export->id))->onQueue(QueueExport::QUEUE_SOURCE_MATERIAL_TEMPLATE_NAME);
            if ($isReverse) {//有背面图的 再请求下队列 分开生成
                $params['imgType'] = SourceMaterialTemplateModel::TEMPLATE_IMG_TYPE_REVERSE;
                $export         = (new ExportDownloadModel)->add(ExportDownloadModel::CLIENT_TYPE_APP, ExportDownloadModel::FILE_TYPE_APP_SOURCE_MATERIAL_TEMPLATE, $params);

                dispatch(new QueueExport($export->id))->onQueue(QueueExport::QUEUE_SOURCE_MATERIAL_TEMPLATE_NAME);
            }
        } catch (Exception $e) {
            throw new ShopException(ShopCodeEnum::ERR_CREATE_MATERIAL_TEMPLATE, $e->getMessage());
        }
        return [];
    }

    /**
     * 合成图片
     * @param $info
     * @param array $createTemplateData
     * @param int $userId
     * @param int $shopId
     * @return array
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public static function generateTemplateImg($info, array $createTemplateData, int $userId,int $shopId): array
    {
        ini_set('max_execution_time', 180);
        ini_set('memory_limit', '-1');
        $valueArray       = json_decode($info['value'], true);
        $fileSystem       = getFileSystem();
        $templateBasePath = sys_get_temp_dir() . '/' . Str::random() . "/sourceMaterialTemplate/{$shopId}";
//        $templateBasePath =  app()->basePath()  .  "/public/storage/sourceMaterialTemplate/{$shopId}";// 测试
        //获取模板文件
        list($uprightTemplatePath, $reverseTemplatePath, $initFileGroup) = self::getPraiseCardTemplate(
            $info['id'],
            $valueArray,
            $fileSystem,
            $templateBasePath
        );

        $userFilePrefix = md5($userId);
        $wmCardUserPath = vsprintf(
            "%s/%s/%s/%s/", [
            $templateBasePath,
            "user",
            substr($userFilePrefix, 0, 2),
            substr($userFilePrefix, 2, 2)
        ]
        );

        if (!$fileSystem->isDirectory($wmCardUserPath)) {
            $fileSystem->makeDirectory($wmCardUserPath, 0777, true);
        }
        $finalWechatPic = $wmCardUserPath . "{$userFilePrefix}_{$userId}_wechat.png";
        foreach ($valueArray["position"] as $picName => $item) {
            switch ($picName) {
                case "qrCode":
                    if (!$createTemplateData['wechatUrl']) {//二维码不存在
                        break;
                    }
                    $query = Builder::create()
                        ->writer(new PngWriter())
                        ->writerOptions([])
                        ->data($createTemplateData['wechatUrl'])
                        ->encoding(new Encoding('UTF-8'))
                        ->errorCorrectionLevel(new ErrorCorrectionLevelHigh())
                        ->size($item['size'])
                        ->margin($item['margin'])
                        ->roundBlockSizeMode(new RoundBlockSizeModeMargin());
                    if (isset($initFileGroup["kFlogo"])) {
                        $query->logoPath($initFileGroup["kFlogo"]);
                        $query->logoResizeToWidth($item['size'] / 4);
                        $query->logoResizeToHeight($item['size'] / 4);
                    }
                    $result = $query->build();
                    $result->saveToFile($finalWechatPic);
                    break;
                case "upright":
                case "reverse":
                    // 正面卡片上的文字信息
                    // 用户卡片正面图
                    if ($picName == 'reverse' && !$reverseTemplatePath) {//没有背面图片时
                        break;
                    }
                    $userImg = $wmCardUserPath . "{$userFilePrefix}_{$userId}_{$picName}.png";
                    $query   = Image::make($picName == "upright" ? $uprightTemplatePath : $reverseTemplatePath);
                    $font_max_len = 26; // 每行最大文字长度
                foreach ($item as $imgAttrName => $imgAttrConfig) {
                        $text = "";
                        $front_data = [];   //文字分组数据
                        switch ($imgAttrName) {
                            case "price":
                                $text = $createTemplateData['price'];
                                break;
                            case "tel":
                                $text = $createTemplateData['tel'];
                                break;
                            case "num":
                                $text = $createTemplateData['num'];
                                break;
                            case "recruitmentTitle":
                                $text = $createTemplateData['recruitmentTitle'];
                                break;
                            case "recruitmentRequire":
                                $text         = $createTemplateData['recruitmentRequire'];
                                $fontMaxLen   = $imgAttrConfig['fontMaxLen'] ?? 13; // 每行最大文字长度
                                $fontMaxLines = $imgAttrConfig['fontMaxLines'] ?? 8; // 最大行数
                                $front_data   = self::getPregSplit($text, $fontMaxLen, $fontMaxLines);//字符串转数组，根据换行符匹配
                                break;
                            case "recruitmentTitleRight":
                                $text = $createTemplateData['recruitmentTitleRight'];
                                break;
                            case "recruitmentRequireRight"://右边详细信息
                                $text         = $createTemplateData['recruitmentRequireRight'];
                                $fontMaxLen   = $imgAttrConfig['fontMaxLen'] ?? 12; // 每行最大文字长度
                                $fontMaxLines = $imgAttrConfig['fontMaxLines'] ?? 8; // 最大行数
                                $front_data   = self::getPregSplit($text, $fontMaxLen, $fontMaxLines);//字符串转数组，根据换行符匹配
                                break;
                            case "recruitmentShopAddress":
                                $text         = $createTemplateData['recruitmentShopAddress'];
                                $fontMaxLen   = $imgAttrConfig['fontMaxLen'] ?? 16; // 每行最大文字长度
                                $fontMaxLines = $imgAttrConfig['fontMaxLines'] ?? 2; // 最大行数
                                $front_data   = self::getPregSplit($text, $fontMaxLen, $fontMaxLines);//字符串转数组，根据换行符匹配
                                if (count($front_data)) {
                                    $front_data[0] = "地址: " . $front_data[0];
                                }
                                break;
                            case "recruitmentExtra":
                                $text = $createTemplateData['recruitmentExtra'];
                                break;
                            case "person":
                                $text = $createTemplateData['person'];
                                break;
                            case "shopName":
                                $text = $createTemplateData['shopName'];
                                break;
                            case "smallNum":
                                $text = $createTemplateData['smallNum'];
                                break;
                            case "qrCode":
                                $query->insert(
                                    $finalWechatPic, $imgAttrConfig['align'],
                                    $imgAttrConfig['x'], $imgAttrConfig['y']
                                );
                                break;
                            default:
                                if (strpos($imgAttrName, 'inputImg') !== false) {
                                    $tempInputImgFile = $wmCardUserPath . "{$userFilePrefix}_{$userId}_{$imgAttrName}_.png";
                                    Image::make($createTemplateData[$imgAttrName])
                                         ->resize($imgAttrConfig['width'], $imgAttrConfig['height'])
                                         ->save($tempInputImgFile);
                                    $query->insert(
                                        $tempInputImgFile, $imgAttrConfig['align'],
                                        $imgAttrConfig['x'], $imgAttrConfig['y']
                                    );
                                } elseif (strpos($imgAttrName, 'input') !== false) {
                                    $text = $createTemplateData[$imgAttrName] ?? '';

                                    // 多行
                                    $fontMaxLen   = $imgAttrConfig['fontMaxLen'] ?? 0; // 每行最大文字长度
                                    $fontMaxLines = $imgAttrConfig['fontMaxLines'] ?? 0; // 最大行数
                                    if ($text && $fontMaxLen && $fontMaxLines) {
                                        $front_data = self::getPregSplit($text, $fontMaxLen,
                                            $fontMaxLines);//字符串转数组，根据换行符匹配
                                    }
                                }
                                break;
                        }
                        if ($text) {
                            if ($front_data && is_array($front_data)) {//多行文字
                                $y = $imgAttrConfig['fontLineSpace'] ?? 350;
                                foreach ($front_data as $k => $v) {
                                    $query->text(
                                        $v, $imgAttrConfig['x'], $imgAttrConfig['y'] + $k * $y,
                                        function ($font) use ($imgAttrConfig, $imgAttrName, $initFileGroup) {
                                            if (isset($imgAttrConfig["color"])) {
                                                $font->color($imgAttrConfig["color"]);
                                            }
                                            if (isset($imgAttrConfig["fontSize"])) {
                                                $font->size($imgAttrConfig["fontSize"]);
                                            }
                                            if (isset($initFileGroup[$imgAttrName . "Front"])) {
                                                $font->file($initFileGroup[$imgAttrName . "Front"]);
                                            }
                                            if (isset($imgAttrConfig["align"])) {
                                                $font->align($imgAttrConfig["align"]);
                                            }
                                        }
                                    );
                                }
                            } else {//单行文字
                                $query->text(
                                    $text, $imgAttrConfig['x'], $imgAttrConfig['y'],
                                    function ($font) use ($imgAttrConfig, $imgAttrName, $initFileGroup) {
                                        if (isset($imgAttrConfig["color"])) {
                                            $font->color($imgAttrConfig["color"]);
                                        }
                                        if (isset($imgAttrConfig["fontSize"])) {
                                            $font->size($imgAttrConfig["fontSize"]);
                                        }
                                        if (isset($initFileGroup[$imgAttrName . "Front"])) {
                                            $font->file($initFileGroup[$imgAttrName . "Front"]);
                                        }
                                        if (isset($imgAttrConfig["align"])) {
                                            $font->align($imgAttrConfig["align"]);
                                        }
                                    }
                                );
                            }
                        }
                    }
                    $resolution = $item['resolution'] ?? "";//图片分辨率
                    if ($resolution) {
                        $resolution = explode('×', $resolution, 2);
                    }
                    if (!$resolution || !is_array($resolution)) {
                        $resolution = [600, 600];//默认
                    }
                    $query->resolution((int)$resolution[0], (int)$resolution[1])->save($userImg);
                    break;
            }
        }

        $ossFileUpright = $wmCardUserPath . "{$userFilePrefix}_{$userId}" . '_upright.png';
        $ossFileReverse = '';
        if ($reverseTemplatePath) {
            $ossFileReverse = $wmCardUserPath . "{$userFilePrefix}_{$userId}" . '_reverse.png';
        }
        return [
            'upright'          => $ossFileUpright,
            'reverse'          => $ossFileReverse,
            'templateBasePath' => $templateBasePath,// 返回文件存储临时目录
        ];
    }

    /**
     * 物料素材模版单个详细
     * @param int $id
     * @return array
     */
    public static function detail(int $id): array
    {
        $data = [];
        $info = SourceMaterialTemplateModel::getInfoById($id);
        if ($info) {
            $data['appValue'] = json_decode($info['appValue'], true);
        }
        return $data;
    }

    /**
     * 中文自动换行
     * @param $string
     * @param $len
     * @return array
     */
    public static function mbStrSplit($string, $len): array
    {
        $start  = 0;
        $strlen = strlen($string);
        $array  = [];
        while ($strlen) {

            // 按指定宽度截断的字符串 将string截断到指定width。其中半角字符计为1，全角字符计为2。 utf-8编码下每个中文字符所占字节为3
            $tempStr = mb_strimwidth($string, 0, ($len * 2) + 1, '', 'UTF-8');
            $string  = str_replace($tempStr, '', $string);
            $array[] = $tempStr;
            $strlen  = strlen($string);
        }
        return $array;
    }

    /**
     * 字符串转数组，根据换行符匹配
     * @param string $text
     * @param int $fontMaxLen
     * @param int $fontMaxLines
     * @return array
     */
    public static function getPregSplit(string $text,int $fontMaxLen, int $fontMaxLines): array
    {
        $frontData = [];
        try {
            $frontDataTemp = preg_split("/([\n]+)/", $text);//匹配换行符
            if (is_array($frontDataTemp)) {
                foreach ($frontDataTemp as $v) {
                    $tmpStr    = self::mbStrSplit($v, $fontMaxLen);
                    $frontData = array_merge($frontData, $tmpStr);
                }
            }
            $frontData = array_slice($frontData, 0, $fontMaxLines);//最大行数
        } catch (Exception $ex) {
            Log::info('getPregSplitErr：', [
                'text'         => $text,
                'fontMaxLines' => $fontMaxLines,
                'msg'          => $ex->getMessage(),
            ]);
        }
        return $frontData;
    }


    /**
     * 物料素材模版单个详细
     * @param int $id
     * @return array
     */
    public static function info(int $id): array
    {
        $info = SourceMaterialTemplateModel::query()->where('id', $id)->first();
        if ($info) {
            $info                     = $info->toArray();
            $info['url']              = self::urlHandle($info['url']);
            $info['reverseUrl']       = self::urlHandle($info['reverseUrl']);
            $info['thumbnail']        = self::urlHandle($info['thumbnail']);
            $info['reverseThumbnail'] = self::urlHandle($info['reverseThumbnail']);
            $info['value']            = $info['value'] && $info['value'] != null ? $info['value'] : "";
            $info['appValue']         = $info['appValue'] && $info['appValue'] != null ? $info['appValue'] : "";
        }
        return $info ?? [];
    }

    /**
     * 物料素材模版配置
     */
    public static function typeConfig(): array
    {
        $data = ConfigModel::getConfigByTypeKey('tools', 'wuliaoTemplateConfig');
        $list = json_decode($data[0]['value'], true);
        $list = $list ?? [];
        if ($list) {
            array_multisort(array_column($list, 'sort'), SORT_ASC, $list);
        }
        return $list;
    }


    /**
     * 新增/编辑物料
     * @param $id
     * @param $name
     * @param $thumbnail
     * @param $type
     * @param $url
     * @param $reverseUrl
     * @param $reverseThumbnail
     * @param $value
     * @param $appValue
     * @param $size
     * @param $sort
     * @param $userId
     * @throws ShopException
     */
    public static function save(
        $id,
        $name,
        $thumbnail,
        $type,
        $url,
        $reverseUrl,
        $reverseThumbnail,
        $value,
        $appValue,
        $size,
        $sort,
        $userId
    ) {
        if ($id) {
            $sourceMaterialTemplateModel = SourceMaterialTemplateModel::query()->where('id', $id)->first();
            if (!$sourceMaterialTemplateModel) {
                throw new ShopException(ShopCodeEnum::ERR_NOT_FOUND_TEMPLATE);
            }
            $oldData = $sourceMaterialTemplateModel->toArray();
            Log::info('sourceMaterialTemplateSave-oldData:', [
                'oldData' => $oldData,
                'userId'  => $userId,
                'id'      => $id,
            ]);
        } else {
            $sourceMaterialTemplateModel               = new SourceMaterialTemplateModel;
            $sourceMaterialTemplateModel->createdByUid = $userId;
        }
        $data = [
            'name'             => $name,
            'url'              => str_replace(FileUtil::domain() . '/', '', $url),
            'reverseUrl'       => str_replace(FileUtil::domain() . '/', '', $reverseUrl),
            'thumbnail'        => str_replace(FileUtil::domain() . '/', '', $thumbnail),
            'reverseThumbnail' => str_replace(FileUtil::domain() . '/', '', $reverseThumbnail),
            'value'            => $value,
            'appValue'         => $appValue,
            'type'             => $type,
            'size'             => $size,
            'sort'             => $sort,
        ];
        Log::info('sourceMaterialTemplateSave-newData:', [
            'newData' => $data,
            'userId'  => $userId,
            'id'      => $id,
        ]);
        try {
            $sourceMaterialTemplateModel->fill($data);
            $sourceMaterialTemplateModel->updatedByUid = $userId;
            $sourceMaterialTemplateModel->save();

        } catch (Exception $exception) {
            throw new ShopException(ShopCodeEnum::ERR_UPDATE_TEMPLATE,'物料编辑记录失败');
        }
    }


    /**
     * 物料素材模版-删除
     * @param $id
     * @param $userId
     * @throws ShopException
     */
    public static function delete($id, $userId)
    {
        $sourceMaterialTemplateModel = SourceMaterialTemplateModel::query()->where('id', $id)->first();
        if (!$sourceMaterialTemplateModel) {
            throw new ShopException(ShopCodeEnum::ERR_NOT_FOUND_TEMPLATE);
        }
        try {
            SourceMaterialTemplateModel::query()->where('id', $id)->update([
                'isDeleted'    => 1,
                'updatedByUid' => $userId,
            ]);
            Log::info('sourceMaterialTemplateDelete:', [
                'id'     => $id,
                'userId' => $userId,
                'data'   => $sourceMaterialTemplateModel->toArray(),
            ]);
        } catch (Exception $exception) {
            throw new ShopException(ShopCodeEnum::ERR_UPDATE_TEMPLATE, '物料删除记录失败');
        }
    }

    /**
     * 物料素材模版列表-后台带分页
     * @param $type
     * @param $name
     * @param $pageSize
     * @param $pageNum
     * @return array
     */
    public static function totalList($type, $name, $pageSize, $pageNum): array
    {
        $paginator = SourceMaterialTemplateModel::query()
                                                ->when($type > 0, function ($query) use ($type) {
                                                    $query->where("type", $type);
                                                })
                                                ->when($name, function ($q) use ($name) {
                                                    $q->where('name', 'like', "%{$name}%");
                                                })
                                                ->orderBy("sort")
                                                ->orderBy("id")
                                                ->paginate($pageSize, ['*'], 'page', $pageNum);
        return [
            'pageNum'  => $paginator->currentPage(),
            'pageSize' => $paginator->perPage(),
            'count'    => $paginator->total(),
            'list'     => $paginator->map(function (SourceMaterialTemplateModel $sourceMaterialTemplateModel) {
                return [
                    'id'               => $sourceMaterialTemplateModel->id,
                    'name'             => $sourceMaterialTemplateModel->name,
                    //模版名称
                    'url'              => self::urlHandle($sourceMaterialTemplateModel->url),
                    //预览图
                    'reverseUrl'       => self::urlHandle($sourceMaterialTemplateModel->reverseUrl),
                    //背面预览图
                    'thumbnail'        => self::urlHandle($sourceMaterialTemplateModel->thumbnail),
                    //缩略图
                    'reverseThumbnail' => self::urlHandle($sourceMaterialTemplateModel->reverseThumbnail),
                    //背面缩略图
                    'type'             => $sourceMaterialTemplateModel->type,
                    //素材类型 1：开业活动免费吃 2 ：开业活动进店送 3 ：招聘海报 4 ：好评卡外卖海报
                    'size'             => $sourceMaterialTemplateModel->size,
                    //模版图片尺寸（cm）
                    'sort'             => $sourceMaterialTemplateModel->sort,
                    //排序 越小越靠前
                    'typeText'         => SourceMaterialTemplateModel::TEMPLATE_TYPE_TEXT[$sourceMaterialTemplateModel->type] ?? "",
                ];
            })
        ];
    }

}
